package dao;


import util.PinyinUtil;

import java.io.File;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Objects;

// 这个类的实例就代表 file_meta 表里的每个记录.
public class FileMeta {
    private int id;
    private String name;
    private String path;
    private boolean isDirectory;

    // 下面两个属性, 在 java 代码中, 可以没有.
    // 都是根据上述的 name 属性来的.
    // 而是可以直接给这个类加两个 get 方法来获取到 pinyin 和 pinyinFirst
    // private String pinyin;
    // private String pinyinFirst;

    private long size;

    // 用这个表示更好阅读的结果
    // private String sizeText;
    // last_modified 是时间戳，1979.1.1 开始算的，这也是一个非常大的数字
    // 直接显示在界面上也不好看，而是要进行格式转换的
    private long lastModified;
    // private String lastModifiedText;

    public String getPinyin() {
        return PinyinUtil.get(name,true);
    }

    public String getPinyinFirst() {
        return PinyinUtil.get(name,false);
    }

    /**
     * 格式化时间的函数
     * @return
     */
    public String getLastModifiedText() {
        // 关于这里的格式化时间的字符串,不要去背容易出错,用的时候去查
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        return dateFormat.format(lastModified);
    }
    public String getSizeText() {

        // 通过这个方法，把 size 的值进行合理的单位换算，变成更易读的结果
        // 单位主要就是四个，Byte，KB，MB，GB

        // 由于单个文件不太可能达到 TB 级别, 只考虑这四个单位就差不多了.
        // 主要是看 size 的大小.
        // 如果 size 是 < 1024 , 单位直接使用 Byte 即可.
        // 如果 size 是 >= 1024 并且 < 1024 * 1024, 单位使用 MB
        // 假设 size 是 1025, 此时显示的结果, 肯定不是 1025 MB..... 1.001 MB
        // .....

        // 这里的关键思路:
        // 1. 比较 size 和 1024 之间的大小关系.
        // 2. 如果 size < 1024 , 直接获取到结果; 如果 size >= 1024, 则除等与 1024, 并且单位升级一下
        String[] units = {"Byte","KB","MB","GB"};
        double curSize = size;
        for (int level = 0; level < units.length; level++) {
            if(curSize < 1024) {
                // 不必继续换算了, 直接使用当前 level 对应的单位即可!
                // 注意 BigDecimal 表示小数很精确，所以传递一个小数更好，我们此处用 double
                return String.format("%.2f" + units[level],new BigDecimal(curSize));
            }
            curSize /= 1024;
        }
        // 当单位升级到 GB 还不够用, 还是就以 GB 为单位就得了.
        return String.format("%.2f GB",new BigDecimal(curSize));
    }

    // 添加构造方法
    public FileMeta(String name, String path, boolean isDirectory, long size, long lastModified) {
        this.name = name;
        this.path = path;
        this.isDirectory = isDirectory;
        this.size = size;
        this.lastModified = lastModified;
    }

    /**
     *  新添构造方法
     * @return
     */
    public FileMeta(File file) {
        // 调用其他的构造方法,用 this(xxx) 来调用,而且必须放在第一行
        // 上面那个构造方法里的参数,文件 File api 里都有对应的得到方法
        /**
        // this(file.getName(), file.getPath(), file.isDirectory(), file.length(),file.lastModified());
        // 注意 file.getPath() 得到的路径是带上 自己的文件名的 ,我们期望不带上,所以用 file.getParent()
         */
        this(file.getName(), file.getParent(), file.isDirectory(), file.length(),file.lastModified());
    }

    /**
     *  自动生成的重写 equals 方法
     * @return
     */
//    @Override
//    public boolean equals(Object o) {
//        if (this == o) return true;
//        if (o == null || getClass() != o.getClass()) return false;
//        FileMeta fileMeta = (FileMeta) o;
//        return isDirectory == fileMeta.isDirectory && name.equals(fileMeta.name) && path.equals(fileMeta.path);
//    }

    @Override
    public boolean equals(Object o) {
        if(this == o) {
            // 判断两个对象是否是同一个实例
            // 看看是不是和自己进行比较
            return true;
        }
        if(null == o) {
            // 传入的对象为空
            return false;
        }
        if(getClass() != o.getClass()) {
            // 传入的对象类型不相同
            return false;
        }
        // 类型相同,可以进行强制转换, 字符串内容比较可以用 equals 方法
        FileMeta fileMeta = (FileMeta) o;
        // 此处应该 .属性 或者 .getXXXX 都是可以的.
        // isDirectory 是 boolean 类型的,可以直接用相等. int 类型的也可以直接用 == 比较
        return this.name.equals(fileMeta.name) && path.equals(fileMeta.path) && isDirectory == fileMeta.isDirectory;
    }

    // 当前已经是重写了 equals 方法,很多 Java 规范里也建议重写 hashCode 方法.
    // 因为如果两个对象的 equals 为 true , 此时他们得到的 hashCode 也应该是相同的
    // 此处代码中,不写 hashCode 也不是不行,毕竟当前不需要把这个 FileMeta 放到 哈希表中去

    @Override
    public int hashCode() {
        return Objects.hash(name, path, isDirectory);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public boolean isDirectory() {
        return isDirectory;
    }

    public void setDirectory(boolean directory) {
        isDirectory = directory;
    }

    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

    public long getLastModified() {
        return lastModified;
    }

    public void setLastModified(long lastModified) {
        this.lastModified = lastModified;
    }
}
